Skip to content

fix tls server name extraction for ipv6 authorities in wasi-http#13686

Open
netliomax25-code wants to merge 2 commits into
bytecodealliance:mainfrom
netliomax25-code:wasi-http-tls-server-name-ipv6
Open

fix tls server name extraction for ipv6 authorities in wasi-http#13686
netliomax25-code wants to merge 2 commits into
bytecodealliance:mainfrom
netliomax25-code:wasi-http-tls-server-name-ipv6

Conversation

@netliomax25-code

Copy link
Copy Markdown
Contributor
  1. The default outbound TLS path in p2 and p3 derives the certificate verification host name (rustls's ServerName) with authority.split(":").next().
  2. An IPv6 authority is bracketed, e.g. [2001:db8::1]:443, so that split returns [2001 and ServerName::try_from rejects it. HTTPS to an IPv6 literal then always fails the handshake, even though the TCP connect uses the full authority and reaches the right peer.

Pull the host out of the authority directly, dropping the brackets for the IPv6 form, in one shared helper used by both sites. Added a unit test covering host:port, IPv4, and the bracketed IPv6 forms.

@netliomax25-code netliomax25-code requested a review from a team as a code owner June 18, 2026 09:55
@netliomax25-code netliomax25-code requested review from dicej and removed request for a team June 18, 2026 09:55
Comment thread crates/wasi-http/src/lib.rs Outdated
/// wrong for the bracketed IPv6 form, so handle it explicitly and return the
/// bare address without brackets, which is what `rustls`' `ServerName` expects.
#[cfg(all(feature = "default-send-request", any(feature = "p2", feature = "p3")))]
fn tls_server_name(authority: &str) -> &str {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this return ServerName directly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, it returns ServerName<'static> now.

Comment thread crates/wasi-http/src/lib.rs Outdated
match authority.split_once(':') {
Some((host, _port)) => host,
None => authority,
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about first trying https://doc.rust-lang.org/std/net/enum.SocketAddr.html#impl-FromStr-for-SocketAddr returning ServerName::IpAddress on success and otherwise trying to split off the : part and passing that to ServerName::try_from?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. The helper now returns ServerName<'static> directly: it parses the authority as a SocketAddr first and returns ServerName::IpAddress on success, which handles the bracketed IPv6 form, and otherwise splits off the port and hands the host to ServerName::try_from. The authority always carries a port at this point (both p2 and p3 append 443/80 when none is given), so IP literals always parse as a SocketAddr. Both call sites just map_err the result now, dropping the local ServerName import and the to_owned(). Updated the unit test to assert on the resulting ServerName.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants